/**
 * 整合请求中的loading、错误捕获、分页，后续还能整合其他的使用场景
 * 提高代码的复用性减少重复代码，减少定义多余的state及其相关的effect副作用
 * @内部实现通过分页来控制列表的请求外部引用只需设置分页来执行也可以通过resetPage方法重置
 * data默认为请求中的data，如果没有data那么就返回最外层的信息
 * 如{data: {a: 1}, success: true} ----> {a: 1}
 * 如{success: true} ----> {success: true}
 */

type resetPage = ({
  dataParams,
  handleResetPage,
}: {
  /** 改变后的查询变量参数不传为默认Api参数中传入的参数（需要对Api参数进行传参设置） */ dataParams?: {
    [key: string]: any;
  };
  /** 除了请求接口之外的其他操作 */ handleResetPage?: () => void;
}) => void;

type useFetch<T> = {
  /** 分页 */ page: page;
  /** 手动设置分页 */ setPage: (e: page) => void;
  /** 数据 */ data: T | undefined;
  /** 等待 */ loading: boolean;
  /** 获取数据 */ getData: (e?: any) => void;
  /** 查询变量改变初始化分页的场景 */ resetPage: resetPage;
};

import { useState, useEffect } from 'react';

import { page } from './typings';

export default function<T>({
  Api,
  initPage = {
    pageSize: 10,
    current: 1,
    total: 0,
  },
}: {
  /** 接口 */ Api: (e?: any) => Promise<any>;
  /** 初始化分页 */ initPage?: page;
}): useFetch<T> {
  const [init, setInit] = useState(true);
  const [page, setPage] = useState(initPage);
  const [data, setData] = useState<T | undefined>();
  const [loading, setLoading] = useState(false);

  const getData = async (e: any = {}) => {
    if (loading) return;
    try {
      setLoading(true);
      const { data, ...otherProps } = await Api(e);
      setPage({
        ...page,
        total: data?.total || data?.total === 0 ? data?.total : page?.total,
      });
      setData(data?.constructor ? data : { ...otherProps }); // 0，null，undefined的情况要做判断，对于只有success字段的情况直接返回根对象
      setLoading(false);
    } catch {
      setLoading(false);
    }
  };

  useEffect(() => {
    init ? setInit(false) : getData();
  }, [page.current, page.pageSize]);

  return {
    page,
    setPage,
    data,
    loading,
    getData,
    resetPage: ({ dataParams, handleResetPage }) => {
      if (page.current === 1) {
        handleResetPage && handleResetPage();
        getData(dataParams);
      } else {
        setPage({
          total: 0,
          current: 1,
          pageSize: page.pageSize,
        });
      }
    },
  };
}
